﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Vux.SVCore.Objects;
using System.Drawing;
using Vux.Helper.Imaging;
using Vux.SVCore.Server.Network;
using Vux.SVCore.Network;
using System.Net.Sockets;
using System.Net;
using System.Threading;
using Vux.SVCore.Delegate;

namespace Vux.SVCore.Server
{
    public class SVCoreServer
    {
        private SocketClient m_socket_handle;
        private string m_str_image_path;
        private string m_str_tinMat;

        public string TinMat
        {
            get { return m_str_tinMat; }
            set { m_str_tinMat = value; }
        }

        private bool m_bl_core_reset_auth;
        /// <summary>
        /// Bộ đếm giới hạn quá trình xác thực xảy ra quá lâu.
        /// Cho phép th.gian xác thực nhỏ hơn 15 giây.
        /// </summary>
        private Timer m_tm_check_svCore;

        // Client image
        private byte[] m_bm_image;

        public byte[] ImageData
        {
            get { return m_bm_image; }
            set { m_bm_image = value; }
        }


        /// <summary>
        /// Đặt thuộc tính server core nằm ở đâu
        /// Nếu svCore nằm ở server. Khi người dùng kết nối tới, tự động server gửi
        /// một gói tin kiểm tra svCore đã được cài đặt trên máy người dùng chưa.
        /// </summary>
        /// <param name="svCoreApp">Nếu true, chương trình nằm ở phía người dùng. Ngược lại nằm ở server</param>
        public SVCoreServer()
        {
            m_bl_core_reset_auth = false;
        }

        // event
        public event AuthCompleteHandler AuthComplete;
        public event SVCoreNotAvailableHandler SVCoreNotAvailable;
        public event SVCoreDisconnectedHandler SVCoreDisconnected;

        protected virtual void OnAuthComplete(object sender, bool state)
        {
            if (AuthComplete != null)
            {
                AuthComplete(sender, state);
            }
        }

        protected virtual void OnSVCoreDisconnected(object sender)
        {
            if (SVCoreDisconnected != null)
            {
                SVCoreDisconnected(sender);
            }
        }

        private bool m_checkSvCore_raise = false;
        /// <summary>
        /// Kích hoạt sự kiện: SVCoreNotAvailble
        /// </summary>
        protected virtual void OnSVCoreNotAvailble()
        {
            if (SVCoreNotAvailable != null && m_checkSvCore_raise == false)
            {
                m_checkSvCore_raise = true;
                SVCoreNotAvailable();
            }
        }

        public string ImagePath
        {
            get { return m_str_image_path; }
            set { m_str_image_path = value; }
        }

        public void AuthClient(IPAddress address, int port)
        {
            // Tạm thời chờ vô hạn, sau khi hoàn tất phải bật bộ đếm hạn chế t.gian
            //enableTimerTestSvCore();
            Connect(address, port);
            // Kết thúc bộ đếm hạn chế t.gian
            //disableTimerTestSvCore();
        }

        private void Connect(IPAddress address, int port)
        {
            m_socket_handle = new SocketClient();
            //m_socket_handle.Connected += new ConnectedEventHandler(_Client_Connected);
            //m_socket_handle.DataArrival += new DataArrivalEventHandler(_Client_DataArrival);

            if (m_socket_handle.Connect(address, port) == true)
            {
                var v_verify = SVCorePacket.GetVerifyPacket();
                m_socket_handle.Send(v_verify);
                var v_packet = m_socket_handle.ReceivePacket();
                ProcessPacketOnServer(v_packet);
                m_socket_handle.CloseConnection();
            }
            else
            {
                OnSVCoreNotAvailble();
            }
        }

        public void Disconnect()
        {
            m_socket_handle.CloseConnection();
        }

        private void enableTimerTestSvCore()
        {
            // Đợi 3 giây cho svCore client phản hồi
            m_tm_check_svCore = new Timer(new TimerCallback(SVCoreNotAvailbleCallBack), null, 15000, -1);
        }

        private void disableTimerTestSvCore()
        {
            if (m_tm_check_svCore != null)
            {
                m_tm_check_svCore.Change(-1, -1);
                m_tm_check_svCore.Dispose();
            }
        }

        private void SVCoreNotAvailbleCallBack(object state)
        {
            // Bộ đếm thời gian đã quá hạn mà không thấy svCore từ client phản hồi
            // m_tm_check_svCore.Change(-1, -1);
            // raise event
            OnSVCoreNotAvailble();
        }

        private void ProcessPacketOnServer(SVCorePacket packet)
        {
            if (packet.Service == SVCoreService.Verify)
            {
                var v_packet = SVCorePacket.GetBmpPacket();
                m_socket_handle.Send(v_packet);
                // Chờ nhận một gói tin tiếp theo
                var v_bmp_packet = m_socket_handle.ReceivePacket();
                if (v_bmp_packet.Service == SVCoreService.BmpResp)
                {
                    ProcessPacketOnServer(v_bmp_packet);
                }
                else
                {
                    // Tiến trình không hợp lệ --> gửi gói tin Auth với cờ False(0);
                    OnAuthComplete(this, false);
                    v_packet = SVCorePacket.GetAuthPacket(new byte[] { 0 });
                    m_socket_handle.Send(v_packet);
                    return;
                }
            }
            else if (packet.Service == SVCoreService.BmpResp)
            {
                var v_verify_state = ProcessBmpResp(packet);
                var v_auth_packet = v_verify_state == true
                    ? SVCorePacket.GetAuthPacket(new byte[] { 1 })
                    : SVCorePacket.GetAuthPacket(new byte[] { 0 });
                OnAuthComplete(this, v_verify_state);
                m_socket_handle.Send(v_auth_packet);
            }
            //else if (packet.Service == SVCoreService.Auth)
            //{
            //    ProcessAuthPacket(packet);
            //}
            else
            {
                // Dịch vụ không hợp lệ --> Out ngay

                var v_packet = SVCorePacket.GetAuthPacket(new byte[] { 0 });
                m_socket_handle.Send(v_packet);
            }
        }

        private void ProcessAuthPacket(SVCorePacket packet)
        {
        }

        private bool ProcessBmpResp(SVCorePacket packet)
        {
            try
            {
                var v_mstream = new System.IO.MemoryStream(packet.Data);
                m_bm_image = packet.Data;

                Bitmap bmp = new Bitmap(v_mstream);
                CImageProcessing a = new CImageProcessing();

                a.HamGiaiTin(bmp);
                m_str_tinMat = a.tingiaima;
                return true;
            }
            catch (Exception)
            {
                OnAuthComplete(this, false);
                return false;
            }
        }

    }
}
